SDL mixer:Tutorials:Playing a WAV Sound from a Custom Resource File using SDL RWops
(NOTE: This tutorial is quite similar to its sister tutorial on Displaying a Bitmap from a Custom Resource File using SDL_RWops. If you've read one, the other will be easily understood due to overlapping content!) If you've read the tutorial on Custom Resource Files by now you should have all of your sound samples safely stored within a custom resource file. Now what? Using a little-known SDL structure called SDL_RWops we can extract the sound data from custom resource files, and then use the Mix_LoadWAV_RW function to load the SDL_RWops structure into a Mix_Chunk. Observe: Mix_Chunk *LoadSound(char *resourcefilename, char *soundfilename) { //Get the sound's buffer and size from the resource file int filesize = 0; char *buffer = GetBufferFromResource(resourcefilename, soundfilename, &filesize); //Load the buffer into a surface using RWops SDL_RWops *rw = SDL_RWFromMem(buffer, filesize); Mix_Chunk *sound = Mix_LoadWAV_RW(rw, 1); //Release the buffer memory free(buffer); //Return the sound return sound; } This LoadSound routine uses SDL_RWops to load a sound from memory. The GetBufferFromResource function does some magic (explained below) and extracts a given sound from the specified custom resource file. The buffer returned by GetBufferFromResource is passed to SDL_RWFromMem which creates for us our very own SDL_RWops structure! This SDL_RWops structure is then passed to Mix_LoadWAV_RW along with a value of 1 as the second parameter. (Passing 1 means that we'd like SDL to automatically release the resource after it has been read. Better safe than sorry!) Mix_LoadWAV_RW spits out a Mix_Chunk structure, and things then progress as normal (see the Playing a WAV Sound File With SDL_mixer tutorial for info on how to play the sound stored within a Mix_Chunk structure). So, what voodoo is performed by GetBufferFromResource? char *GetBufferFromResource(char *resourcefilename, char *resourcename, int *filesize) { //Try to open the resource file in question int fd = open(resourcefilename, O_RDONLY); if (fd < 0) { perror("Error opening resource file"); exit(1); } //Make sure we're at the beginning of the file lseek(fd, 0, SEEK_SET); //Read the first INT, which will tell us how many files are in this resource int numfiles; read(fd, &numfiles, sizeof(int)); //Get the pointers to the stored files int *filestart = (int *) malloc(numfiles); read(fd, filestart, sizeof(int) * numfiles); //Loop through the files, looking for the file in question int filenamesize; char *buffer; int i; for(i=0;i Phew! That's a whole lot of voodoo! But most of it should be familiar to you if you've read the Custom Resource Files tutorial. Basically, GetBufferFromResource loops through the various entries in our custom resource file, reading the filename strings to find one that matches the char *resourcename parameter. If it finds the file it's looking for, it loads the file data into a buffer of type char and returns it. GetBufferFromResource also modifies the data pointed to by filesize, as the size of the buffer must be known when using the SDL_RWFromMem function! These two routines are all you need to extract a sound from a custom resource file (assuming you've formatted your resource file as we did in the Custom Resource Files tutorial) and load it into a Mix_Chunk. Source code * Click here to download the full source code, which loads a sound from a custom resource file and plays it. Category:C Category:SDL Mixer